package com.ems.util;

import com.alibaba.fastjson.JSONArray;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.security.MessageDigest;
import java.text.DecimalFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @Author: Wuzh
 * @Description: 工具类
 * @Date Created in 13:46 2020/9/10
 * @return
 */
public class CommonUtil {


    public static final SimpleDateFormat sdf = new SimpleDateFormat ( "yyyyMMdd" );


    public static String getCurrentSimpleDate () {
        return sdf.format ( Calendar.getInstance ().getTime () );
    }


    public static Date getCurrDate (int isMin) {
        SimpleDateFormat sdFormat = null;
        if ( isMin == 1 ) {
            sdFormat = new SimpleDateFormat ( "yyyy-MM-dd HH:mm:ss SSS" );
        } else {
            sdFormat = new SimpleDateFormat ( "yyyy-MM-dd HH:mm:ss" );
        }
        Date date = new Date ();
        String dateString = sdFormat.format ( date );
        ParsePosition pos = new ParsePosition ( 0 );
        Date currentTime_2 = sdFormat.parse ( dateString, pos );
        return currentTime_2;
    }

    /**
     * 将时间转化成指定格式-Date-String
     * @param date
     * @param format
     * @return String
     */
    public static String getDateStrFormat (Date date, String format) {
        String reString = "";
        try {
            SimpleDateFormat sdFormat = new SimpleDateFormat ( format );
            //Date date = sdFormat.parse(orDate);
            reString = sdFormat.format ( date );
        } catch ( Exception e ) {
            // TODO: handle exception
        }
        return reString;
    }

    /**
     * 将整数缩小固定倍数，并保留三位小数点
     * @param value    十进制整数
     * @param multiple 缩小的倍数
     * @param pointer  保留的小数点
     * @return
     */
    public static String parseDecimalPoint (int value, int multiple, int pointer) {
        if ( value == 0 || value == 0 ) {
            return "0.0";
        }
        if ( value < 0 ) {
            // 负数
            value = - value;
            double v = 1.0 * value / multiple;
            String strNumber = String.format ( "%." + pointer + "f", v );
            return "-".concat ( strNumber );
        }
        double v = 1.0 * value / multiple;
        String strNumber = String.format ( "%." + pointer + "f", v );
        return strNumber;
    }


    /**
     * int类型转字符串，由于子设备上行数据均是扩大100倍
     * 目前采取除以100，并判断有误小数，无小数直接返回整数
     * @param value
     * @return
     */
    public static String parseIntToStr (int value) {
        double v = 1.0 * value / 100;
        String strValue = String.valueOf ( v );
        String substring = strValue.substring ( strValue.lastIndexOf ( "." ) + 1 );
        if ( substring.length () > 2 ) {
            DecimalFormat decimalFormat = new DecimalFormat ( "0.00" );
            strValue = decimalFormat.format ( v );//format 返回的是字符串
        }
        int iInt = Integer.parseInt ( substring );
        if ( iInt <= 0 ) {
            // 整数
            strValue = strValue.substring ( 0, strValue.lastIndexOf ( "." ) );
        }
        return strValue;
    }

    /**
     * 单体电池温度处理，-40度处理
     * @param value
     * @return
     */
    public static String parseIntToStrTemp (int value) {
        if ( value <= 0 ) {
            return "0";
        }
        double v = 1.0 * value / 100;
        v -= 40;
        String strValue = String.valueOf ( v );
        String substring = strValue.substring ( strValue.lastIndexOf ( "." ) + 1 );
        if ( substring.length () > 2 ) {
            DecimalFormat decimalFormat = new DecimalFormat ( "0.00" );
            strValue = decimalFormat.format ( v );//format 返回的是字符串
        }
        int iInt = Integer.parseInt ( substring );
        if ( iInt <= 0 ) {
            // 整数
            strValue = strValue.substring ( 0, strValue.lastIndexOf ( "." ) );
        }
        return strValue;
    }

    /**
     * 生成token
     * @return
     */
    public static String getToken () {
        return UUID.randomUUID ().toString ();
    }


    public static void main (String[] args) {
        String s = MD5Util ( "123qwe!@#" );
        System.out.println ( s );
    }

    /***
     * MD5加密（生成唯一的MD5值）
     * @param key
     * @return
     * @throws Exception
     */
    public static String MD5Util (String key) {
        /*
         * 加密需要使用JDK中提供的类
         */
        StringBuffer sb = new StringBuffer ();
        try {
            MessageDigest digest = MessageDigest.getInstance ( "MD5" );
            byte[] bs = digest.digest ( key.getBytes () );
            /*
             *  加密后的数据是-128 到
             *  127 之间的数字，这个数字也不安全。
             *   取出每个数组的某些二进制位进行某些运算，得到一个具体的加密结果
             *   0000 0011 0000 0100 0010 0000 0110 0001
             *  &0000 0000 0000 0000 0000 0000 1111 1111
             *  ---------------------------------------------
             *   0000 0000 0000 0000 0000 0000 0110 0001
             *   把取出的数据转成十六进制数
             */
            for ( byte b : bs ) {
                int x = b & 255;
                String s = Integer.toHexString ( x );
                if ( x > 0 && x < 16 ) {
                    sb.append ( "0" );
                    sb.append ( s );
                } else {
                    sb.append ( s );
                }
            }
        } catch ( Exception e ) {
            System.out.println ( "加密失败" );
        }
        return sb.toString ();
    }


    /**
     * 将字符串的值扩大指定倍数后，取整数部分返回
     * @param value：要扩大的字符串小数
     * @param multiple：要扩大的倍数
     * @return：返回扩大后取整的部分
     */
    public static String expand (String value, int multiple) {
        if ( multiple < 0 ) {
            return "0";
        }
        double d = Double.parseDouble ( value );
        if ( multiple > 1 ) {
            d = d * multiple;
        }
        String s = String.valueOf ( d );
        s = s.substring ( 0, s.indexOf ( "." ) );
        return s;
    }

    /**
     * 计算两个时间差（h）
     * @param startDate
     * @param endDate
     * @return
     */
    public static Double timeDifference (Date startDate, Date endDate) {
        if ( startDate == null || endDate == null ) {
            return 0.0;
        }
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime () - startDate.getTime ();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒//输出结果
        long sec = diff % nd % nh % nm / ns;
        // 计算为以小时为单位的小数时间
        double timeout = 0;
        if ( day > 0 ) {
            timeout += ( day * 24 );
        }
        if ( hour > 0 ) {
            timeout += hour;
        }
        if ( min > 0 ) {
            timeout += ( 1.0 * min / 60 );
        }
        timeout += ( 1.0 * sec / 3600 );
        BigDecimal two11 = new BigDecimal ( timeout );
        timeout = two11.setScale ( 2, BigDecimal.ROUND_HALF_UP ).doubleValue ();
        return timeout;
    }


    /**
     * 汉字转拼音
     * @param chinese
     * @return
     */
    public String changeSpell (String chinese) {
        //将汉字参数去除空格后转化为数组
        char[] chineseArr = chinese.trim ().toCharArray ();
        //定义一个字符串
        StringBuilder spell = new StringBuilder ();
        //输出格式
        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat ();
        /**
         * 输出大小写设置
         * LOWERCASE:输出小写
         * UPPERCASE:输出大写
         */
        format.setCaseType ( HanyuPinyinCaseType.LOWERCASE );
        /**
         * 输出音标设置
         * WITH_TONE_MARK:直接用音标符（必须设置WITH_U_UNICODE，否则会抛出异常）
         * WITH_TONE_NUMBER：1-4数字表示音标
         * WITHOUT_TONE：没有音标
         */
        format.setToneType ( HanyuPinyinToneType.WITHOUT_TONE );
        /**
         * 特殊音标ü设置
         * WITH_V：用v表示ü
         * WITH_U_AND_COLON：用"u:"表示ü
         * WITH_U_UNICODE：直接用ü
         */
        format.setVCharType ( HanyuPinyinVCharType.WITH_U_UNICODE );

        try {
            for ( int i = 0; i < chineseArr.length; i++ ) {
                //判断是否是汉字
                if ( Character.toString ( chineseArr[i] ).matches ( "[\\u4E00-\\u9FA5]+" ) ) {
                    //如果是多音字，返回多个拼音的数组
                    String[] pys = PinyinHelper.toHanyuPinyinStringArray ( chineseArr[i], format );
                    //只取数组中的第一个
                    spell.append ( pys[0] );
                } else {
                    //如果不是汉字直接拼接到spell中
                    spell.append ( chineseArr[i] );
                }
            }
        } catch ( BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination ) {
            badHanyuPinyinOutputFormatCombination.printStackTrace ();
        }
        return spell.toString ().toUpperCase ();
    }
}
